module uPMips(
input Reset,
input  Clk,
input [31:0] PortIn,
output [31:0] PortOut
);

/* bloque  registro Alu */
wire [31:0] wAluResult;
//wire [31:0] wAluResultReg;

/* bloque  registro a  b y MDR*/
wire [31:0] wMemData;
wire [31:0] wReadDataA;
wire [31:0] wReadDataB;
//wire [31:0] wA;
//wire [31:0] wB;
//wire [31:0] wMDRout;

/* bloque alu control*/
wire [1:0] wAluOp;
//wire [5:0] waddress; input 
//wire [3:0]  wAluOperacion; output

/* bloque alu*/
wire [31:0] wMux4Alu;
wire [31:0] wMux2Alu;
wire [3:0]  wAluOperacion;
//wire wZero; output 
//wire wAluResult; output 

/* bloque RegisterFile*/
wire [4:0] wReadRegA; //wire [25:21] rs ; 
wire [4:0] wReadRegB; //wire [20:16] rt ;
wire [4:0] wWriteRegister;
wire [31:0] wWriteData;
wire wRegWrite;
//wire [31:0] wReadDataA;
//wire [31:0] wReadDataB;

/* bloque Instruction Register*/
wire wIRWrite;
//wire [31:0] wMemData;  entrada
//wire [5:0] wInstruccion, //wire wInstruccion [31:26];
//wire [4:0] wReadRegA; //wire [25:21] rs ; ---
//wire [4:0] wReadRegB; //wire [20:16] rt ;---
//wire [15:0] waddress; wire  waddress [15:0] ---


/* bloque Mux  MuA , MuxMDR y MuxPC*/
wire [31:0] wPCActual;
wire [31:0] wA;
wire wAluSrcA;
//wire [31:0] wMux2Alu; ---
wire [31:0] wMDRout;
wire [31:0] wAluResultReg;
wire  wMemtoReg;
//wire [31:0] wWriteData; ----
//wire [31:0] wPCActual;
//wire [31:0] wAluResultReg; //entrada tambien
wire wlorD;
//wire [31:0] wMemAddress ;---

wire wPCWriteCond;
wire wPcWrite;
wire wOr;
wire wAnd;

/* bloque PC counter*/
wire wZero;
assign   wAnd =  wPCWriteCond & wZero;
assign   wOr =  wAnd | wPcWrite;
//wire [31:0] wPcSiguienteDos;
wire [31:0] wPcSiguiente;
//wire [31:0] wPCActual;

/* bloque Mux B*/
wire [31:0] wB;
reg [31:0] RegCuatro = 32'h 00_00_00_04;
wire [31:0] wOutSignExt;
wire [31:0] wShiftUno;
wire [1:0] wAluSrcB;
//wire [31:0] wMux4Alu;

wire [15:0] waddress; 

/* bloque Mux Shift Uno y Dos*/
//wire [31:0] wOutSignExt; // por que es la misma entrada al mux de cuatro
//wire [31:0] wShiftUno --
wire [25:0] wConcatenado;	//5		    //5		       //16
assign wConcatenado = {wReadRegA,wReadRegB,waddress};
//wire [28:0] wShiftDos

/* bloque Control */
//reg Clk;
//reg Reset;
wire [5:0] wInstruccion; 
//wire [1:0] wAluSrcB;

/* bloque Mux  Instruction Reg*/
 //wire [4:0] wReadRegB; //wire [20:16] rt ; entrada
// wire [15:11] waddress ;
wire wRegDst;


/* bloque Memoria Ram Rom*/
wire wMemRead;
wire wMemWrite;
wire [31:0] wMemAddress ;
//wire [31:0] wMux4Alu; lo que le sale al registro B le entra a la memoria
//wire [31:0] wMemData;  salida

/* bloque SignExtension */
//wire [15:0] waddress; 
//wire [31:0] wOutSignExt; ---


/* bloque Mux Jump */
//wire [31:0] wAluResult;
//wire [31:0] wPcSiguiente;
wire [27:0] wShiftDos;
wire [1:0] wPcSource;
//wire [31:0] wMuxJump;
wire [31:0] wConcatenaJump;
assign wConcatenaJump = {wPCActual[31:28],wShiftDos};

/* bloque Shift2Right */
//wire [31:0] wPcCount;
wire [31:0] wPcSiguienteDos;


Shift2LeftUno inShift2LeftUnoUno(.DataIn(wOutSignExt),.DataOut(wShiftUno));
Shift2Left inShift2LeftDos(.DataIn(wConcatenado),.DataOut(wShiftDos));
Shift2Right inShift2RightUno(.DataIn(wPCActual),.DataOut(wPcSiguienteDos));

MuxCuatro Mux4_Jump(.AluSrcB(wPcSource),.InCero(wAluResult),.InUno(wAluResultReg),.InDos(wConcatenaJump),.InTres(0),.Out2Alu(wPcSiguiente));
PcCouter pcCounter(.Reset(Reset),.Clk(Clk),.PCSiguiente(wPcSiguiente),.PcWrite(wOr),.PCActual(wPCActual));
RegisterFile RegFile(.Clk(Clk),.Reset(Reset),.PortIn(PortIn),.PortOut(PortOut),.RegWrite(wRegWrite),.ReadRegA(wReadRegA),.ReadRegB(wReadRegB),.WriteRegister(wWriteRegister),.WriteData(wWriteData),.ReadDataA(wReadDataA),.ReadDataB(wReadDataB));
InstrutionRegister InsReg(.clk(Clk),.IRWrite(wIRWrite),.dIn(wMemData),.instruction(wInstruccion),.rs(wReadRegA),.rt(wReadRegB),.rd(waddress[15:11]),.shamtFunct(waddress[10:0]));
//InstructionRegister InstReg(.clk(Clk),.IRWrite(wIRWrite),.dIn(wMemData),/*.port(),*/.instruction(wInstruccion),.rs(wReadRegA),.rt(wReadRegB),.address(waddress));
Mux2_31 Mux32_A(.In0(wPCActual),.In1(wA),.Sel(wAluSrcA),.Out(wMux2Alu)); 
Mux2_31 Mux32_MDR(.In0(wAluResultReg),.In1(wMDRout),.Sel(wMemtoReg),.Out(wWriteData));
Mux2_31 Mux32_PC(.In0(wPcSiguienteDos),.In1(wAluResultReg),.Sel(wlorD),.Out(wMemAddress));

MemoriaRamRom Mem(.Clk(Clk),.MemRst(Reset),.MemAddress(wMemAddress),.WriteData(wMux4Alu),.MemWrite(wMemWrite),.MemRead(wMemRead),.MemData(wMemData));
MuxCuatro Mux4_B(.AluSrcB(wAluSrcB),.InCero(wB),.InUno(RegCuatro),.InDos(wOutSignExt),.InTres(wShiftUno),.Out2Alu(wMux4Alu));

SignExtend SignExtension(.InSignExt(waddress),.OutSignExt(wOutSignExt)); //done

Control Ctl(.Clk(Clk), .Reset(Reset), .Op(wInstruccion), .PCWriteCond(wPCWriteCond),.PCWrite(wPcWrite), .lorD(wlorD),.MemRead(wMemRead),.MemWrite(wMemWrite),.MemtoReg(wMemtoReg), .IRWrite(wIRWrite),
 .PCSource(wPcSource), .ALUOp(wAluOp),.ALUSrcB(wAluSrcB), .ALUSrcA(wAluSrcA),.RegWrite(wRegWrite),.RegDst(wRegDst));

Registros A(.clk(Clk),.reset(Reset),.dIn(wReadDataA),.dOut(wA)); //done
Registros B(.clk(Clk),.reset(Reset),.dIn(wReadDataB),.dOut(wB)); //done

Registros AluOut(.clk(Clk),.reset(Reset),.dIn(wAluResult),.dOut(wAluResultReg)); // done
Registros MDR(.clk(Clk),.reset(Reset),.dIn(wMemData),.dOut(wMDRout)); //done
Alu alu(.Shampt(waddress[10:6]),.DatoInA(wMux2Alu),.DatoInB(wMux4Alu),.Operacion(wAluOperacion),.AluResult(wAluResult),.Zero(wZero)); // done
//Alu alu(.DatoInA(wMux2Alu),.DatoInB(wMux4Alu),.Operacion(wAluOperacion),.AluResult(wAluResult),.Zero(wZero)); // done

AluControl AluCtl(.Opcode(wInstruccion),.ALUOp(wAluOp),.Funct(waddress [5:0]),.Operacion(wAluOperacion)); //done

Mux2 muxInstReg(.In0(wReadRegB),.In1(waddress [15:11]),.Sel(wRegDst),.Out(wWriteRegister));
endmodule 